package core

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
	"net"
)

const (
	Package_End_Flag = 0x01
)

type Package struct {
	Length   uint16 //数据包长度，在消息体长度上+3
	Payloads []byte //消息体数据
	EndFlag  byte   //此字节即可以做为结束符标志位，也可以作为版本号，并非一直不变的。
}

func NewPackage(data []byte) *Package {
	return &Package{Length: uint16(len(data)) + 3, Payloads: data, EndFlag: Package_End_Flag}
}

func (p *Package) GetBytes() []byte {
	bufs := bytes.NewBuffer(nil)

	if err := binary.Write(bufs, binary.BigEndian, p.Length); err != nil {
		return nil
	}

	bufs.Write(p.Payloads)

	bufs.WriteByte(p.EndFlag)

	return bufs.Bytes()
}

// 发送数据包
func (p *Package) WritePackage(conn net.Conn) error {
	if conn == nil {
		return nil
	}
	buf := p.GetBytes()
	for len(buf) > 0 {
		n := 0
		var err error
		//如果是大包，则分包发送
		if len(buf) > 1460 {
			n, err = conn.Write(buf[0:1460])
		} else {
			n, err = conn.Write(buf)
		}

		if err != nil {
			return err
		}
		buf = buf[n:]
	}
	return nil
}

// 返回包数据、包版本号
func ReadPackage(conn net.Conn) ([]byte, byte, error) {
	//读取包长度
	buffer := make([]byte, 2)
	_, err := io.ReadFull(conn, buffer)
	if err != nil {
		return nil, 0, err
	}

	//读取包体
	length := binary.BigEndian.Uint16(buffer)
	data := make([]byte, length)
	_, err = io.ReadFull(conn, data)
	if err != nil {
		return nil, 0, err
	}

	//对包结束位进行对比
	if data[length-1] != Package_End_Flag {
		return nil, 0, errors.New(Error_Package_EndFlag)
	}

	return data[0 : length-1], data[length-1], nil
}
